package com.qingdai.ordercenter.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.qingdai.business.emuns.Commodity;
import com.qingdai.business.emuns.Coupon;
import com.qingdai.business.emuns.Order;
import com.qingdai.business.emuns.Shop;
import com.qingdai.business.entities.CommonResult;
import com.qingdai.business.service.CommodityService;
import com.qingdai.business.service.CouponService;
import com.qingdai.business.service.OrderService;
import com.qingdai.business.service.ShopService;
import com.qingdai.business.utils.JwtUtil;
import com.qingdai.business.utils.TimeUtil;
import com.sun.xml.bind.v2.TODO;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 商品 前端控制器
 * </p>
 *
 * @author LiuZiMing
 * @since 2024-01-26
 */
@RestController
@RequestMapping("/order")
@Tag(name = "订单")
public class OrderController {
    @Resource
    private OrderService orderService;
    @DubboReference
    private ShopService shopService;
    @DubboReference
    private CouponService couponService;
    @DubboReference
    private CommodityService commodityService;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private TimeUtil timeUtil;

    {
    }

    //获取所有订单信息
    @GetMapping("/all")
    @Operation(summary = "获取所有订单", description = "获取所有订单")
    public CommonResult getAll() {
        List<Order> allCarts = orderService.list();
        return new CommonResult(200, "获取所有订单成功", allCarts);
    }

    //测试全局事务
    @GetMapping("/test")
    @GlobalTransactional
    @Operation(summary = "test", description = "test")
    public CommonResult test() {
        try {
            boolean orderCreateResult = orderService.save(new Order(null, 1, 1, 1, "1", "1", "2024-03-05 12:00:00", "0", "0", "0", "0", "0", "1", 1.1));
            if (!orderCreateResult) {
                throw new Exception("订单创建失败");
            }
            return new CommonResult(200, "订单创建成功");
        } catch (Exception exception) {
            return new CommonResult(400, "订单创建失败");
        }
    }

    @GetMapping("/jwt")
    @Operation(summary = "用户获取自己订单", description = "用户获取自己订单")
    public CommonResult getOrderByJwt(HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        LambdaQueryWrapper<Order> w = new LambdaQueryWrapper<>();
        w.eq(Order::getBuyerId, jwtUserId);
        List<Order> allCarts = orderService.list(w);
        return new CommonResult(200, "获取本人所有订单成功", allCarts);
    }

    //创建新订单
    @PostMapping("/jwt")
    @GlobalTransactional
    @Operation(summary = "创建新订单", description = "创建新订单")
    @Parameters({
            @Parameter(name = "deliverAddressId", description = "收货地址id", required = true),
            @Parameter(name = "shopId", description = "店铺id", required = true),
            @Parameter(name = "commodityIdList", description = "商品id列表", required = true),
            @Parameter(name = "commodityNumberList", description = "商品数量列表", required = true),
            @Parameter(name = "userCouponIdList", description = "使用优惠卷IdList", required = true),
            @Parameter(name = "commodityPaymentList", description = "实际支付价格List", required = true),
            @Parameter(name = "totalPayment", description = "实际支付总计", required = true),
    })
    public CommonResult createOrderByJwt(@RequestParam(required = true) Integer deliverAddressId,
                                         @RequestParam(required = true) Integer shopId,
                                         @RequestParam(required = true) String commodityIdList,
                                         @RequestParam(required = true) String commodityNumberList,
                                         @RequestParam(required = true) String useCouponIdList,
                                         @RequestParam(required = true) String commodityPaymentList,
                                         @RequestParam(required = true) Double totalPayment,
                                         HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        String now = timeUtil.getNow();
        String[] useCouponId = useCouponIdList.split(",");
        for (int i = 0; i < useCouponId.length; i++) {
            if (1 != couponService.getById(useCouponId).getEnable()) {
                return new CommonResult(400, "请勿选择已使用的优惠卷");
            }
        }
        for (int i = 0; i < useCouponId.length; i++) {
            if (3 == Integer.parseInt(couponService.getById(useCouponId).getRule())) {
                if (totalPayment < Double.parseDouble(couponService.getById(useCouponId).getRuleDetail().split("-")[0])) {
                    return new CommonResult(400, "请勿选择未满足满减条件的优惠卷");
                }
            }
        }
        for (int i = 0; i < useCouponId.length; i++) {
            try {
                boolean changeCouponEnableResult = couponService.saveOrUpdate(new Coupon(Integer.valueOf(useCouponId[i]), null, null, null, null, null, -1));
                if (!changeCouponEnableResult) {
                    throw new Exception("创建订单失败(优惠卷状态更新失败)");
                }
            } catch (Exception exception) {
                return new CommonResult(400, "创建订单失败(优惠卷状态更新失败)");
            }
        }
        String[] commodityIdListt = commodityIdList.split(",");
        String[] commodityNumberListt = commodityNumberList.split(",");
        for (int i = 0; i < commodityIdListt.length; i++) {
            Integer number = commodityService.getById(commodityIdListt[i]).getNumber() - Integer.parseInt(commodityNumberListt[i]);
            if (number < 0) {
                return new CommonResult(400, "id为" + commodityIdListt[i] + "的商品库存不足");
            }
            try {
                boolean changeCommodityNumberResult = commodityService.saveOrUpdate(new Commodity(Integer.valueOf(commodityIdListt[i]), null, null, null, null, null, number, null));
                if (!changeCommodityNumberResult) {
                    throw new Exception("创建订单失败(商品库存更新失败)");
                }
            } catch (Exception exception) {
                return new CommonResult(400, "创建订单失败(商品库存更新失败)");
            }
        }
        try {
            boolean orderCreateResult = orderService.save(new Order(null, deliverAddressId, shopId, jwtUserId, commodityIdList, commodityNumberList, now, "0", "0", "0", "0", useCouponIdList, commodityPaymentList, totalPayment));
            if (!orderCreateResult) {
                throw new Exception("创建订单失败");
            }
        } catch (Exception exception) {
            return new CommonResult(400, "创建订单失败");
        }
        return new CommonResult(200, "创建订单成功");
    }

    //根据id更新订单信息
    @PutMapping("/jwt/id")
    @Operation(summary = "更新订单", description = "根据id更新订单")
    @Parameters({
            @Parameter(name = "id", description = "id", required = true),
            @Parameter(name = "deliverAddressId", description = "收货地址id", required = false),
            @Parameter(name = "shopId", description = "店铺id", required = false),
            @Parameter(name = "buyerId", description = "卖家id", required = false),
            @Parameter(name = "commodityIdList", description = "商品id列表", required = false),
            @Parameter(name = "commodityNumberList", description = "商品数量列表", required = false),
            @Parameter(name = "creationTime", description = "订单创建时间", required = false),
            @Parameter(name = "paymentTime", description = "订单支付时间", required = false),
            @Parameter(name = "sendTime", description = "发货时间", required = false),
            @Parameter(name = "trackingNumber", description = "快递单号", required = false),
    })
    public CommonResult updateOrderById(@RequestParam Integer id,
                                     @RequestParam(required = false) Integer deliverAddressId,
                                     @RequestParam(required = false) Integer shopId,
//                                    @RequestParam(required = false) Integer buyerId,
                                     @RequestParam(required = false) String commodityIdList,
                                     @RequestParam(required = false) String commodityNumberList,
                                     @RequestParam(required = false) String creationTime,
                                     @RequestParam(required = false) String paymentTime,
                                     @RequestParam(required = false) String sendTime,
                                     @RequestParam(required = false) String trackingNumber,
                                     HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        Order order = orderService.getById(jwtUserId);
        if (order == null) {
            return new CommonResult(404, "订单id非法");
        }
        if (!Objects.equals(order.getBuyerId(), jwtUserId)) {
            return new CommonResult(400, "请勿修改他人订单");
        }
        boolean orderUpdateResult = orderService.updateById(new Order(null, deliverAddressId, shopId, jwtUserId, commodityIdList, commodityNumberList, creationTime, paymentTime, sendTime, null, trackingNumber, null, null, null));
        if (!orderUpdateResult) {
            return new CommonResult(400, "更新订单信息失败");
        }
        return new CommonResult(200, "更新订单信息成功");
    }

    //根据id获取订单信息
    @GetMapping("/jwt/id")
    @Operation(summary = "根据id获取订单", description = "根据id获取订单")
    @Parameters({
            @Parameter(name = "id", description = "id", required = true),
    })
    public CommonResult getOrderById(@RequestParam(required = true) Integer id,
                                     HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        Order order = orderService.getById(id);
        if (order == null) {
            return new CommonResult(404, "根据id:" + id + ",未找到订单");
        }
        if (order.getBuyerId() != jwtUserId) {
            return new CommonResult(404, "请勿查询他人订单");
        }
        return new CommonResult(200, "根据id:" + id + ",获取订单成功", order);
    }

    //根据id移除订单信息
    @DeleteMapping("/jwt/id")
    @Operation(summary = "根据id移除订单", description = "根据id移除订单")
    @Parameters({
            @Parameter(name = "id", description = "id", required = true),
    })
    public CommonResult removeOrderById(@RequestParam(required = true) Integer id,
                                        HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        Order order = orderService.getById(id);
        if (order == null) {
            return new CommonResult(404, "根据id:" + id + ",未找到订单");

        }
        if (!Objects.equals(order.getBuyerId(), jwtUserId)) {
            return new CommonResult(404, "请勿删除他人订单");
        }
        boolean orderRemoveResult = orderService.removeById(id);
        if (!orderRemoveResult) {
            return new CommonResult(400, "更新订单信息失败");
        }
        orderService.removeById(id);
        return new CommonResult(200, "根据id:" + id + ",移除订单成功");

    }

    //根据shopId获取订单信息
    @GetMapping("/jwt/shopId")
    @Operation(summary = "根据id获取订单", description = "根据id获取订单")
    @Parameters({
            @Parameter(name = "id", description = "id", required = true),
    })
    public CommonResult getOrderByShopId(@RequestParam(required = true) Integer shopId,
                                         HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();

        MPJQueryWrapper mpjQueryWrapper = new MPJQueryWrapper<Order>();
        mpjQueryWrapper.select("*").eq("shop_id", shopId);
        List<Order> orderList = orderService.list(mpjQueryWrapper);
        if (orderList == null) {
            return new CommonResult(404, "未找到订单");
        }
        Order order = orderList.get(0);
        Integer shopIdByOrder = order.getShopId();
        Integer sellerId = shopService.getById(shopIdByOrder).getSellerId();
        if (!Objects.equals(jwtUserId, sellerId)) {
            return new CommonResult(400, "请勿查询他人店铺订单");
        }
        return new CommonResult(200, "获取订单成功", orderList);
    }

    @GetMapping("/jwt/pay/id")
    @Operation(summary = "根据id支付", description = "根据id支付")
    @Parameters({@Parameter(name = "id", description = "id", required = true)})
    public CommonResult changePayTimeByIdResult(@RequestParam(required = true) Integer id,
                                                HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        Integer sellerId = shopService.getById(orderService.getById(id).getShopId()).getSellerId();
        if (sellerId != jwtUserId) {
            return new CommonResult<>(400, "请勿操作他人订单支付");
        }
        String payTime = timeUtil.getNow();
        Boolean payCommodityResult = orderService.saveOrUpdate(new Order(id, null, null, null, null, null, null, payTime, null, null, null, null, null, null));
        if (!payCommodityResult) {
            return new CommonResult<>(400, "支付失败");
        }
        return new CommonResult(200, "支付成功");
    }

    @GetMapping("/jwt/send/id")
    @Operation(summary = "根据id发货", description = "根据id发货")
    @Parameters({@Parameter(name = "id", description = "id", required = true)})
    public CommonResult deliverOrderByIdAndJwt(@RequestParam(required = true) Integer id,
                                               @RequestParam(required = true) String trackingNumber,
                                               HttpServletRequest request) {
        CommonResult result = jwtUtil.getUserIdByRequest(request);
        Integer jwtUserId = (Integer) result.getData();
        Integer sellerId = shopService.getById(orderService.getById(id).getShopId()).getSellerId();
        if (!Objects.equals(sellerId, jwtUserId)) {
            return new CommonResult<>(400, "请勿操作他人订单发货状态");
        }
        String sendTime = timeUtil.getNow();
        Boolean sentCommodityResult = orderService.saveOrUpdate(new Order(id, null, null, null, null, null, null, null, sendTime, null, trackingNumber, null, null, null));
        if (!sentCommodityResult) {
            return new CommonResult<>(400, "发货失败");
        }
        return new CommonResult(200, "发货成功");
    }
}
